
#include <memory.h>
#include <stdio.h>

#define LG_CORE

#include "lg_shader.h"

static const char* MISS_ERR = "miss vertex or fragment shader source";
static struct {
	LGConfig* config;
	LGShaderBackend* backend;
}gCtx = { 0 };

static void
freeShader(void* ref) {
	LGShader* shader = ref;
	gCtx.backend->freeShader(shader);
	for (unsigned i = 0; i < shader->vsCount; i++) {
		free(shader->vs[i].data);
	}
	for (unsigned i = 0; i < shader->fsCount; i++) {
		free(shader->fs[i].data);
	}
}


LG_API int
lgInitShaderContext(LGConfig* config, LGShaderBackend* backend) {
	gCtx.config = config;
	gCtx.backend = backend;
	return 0;
}

LG_API LGShader*
lgNewShader() {
	size_t size = gCtx.backend->sizeofShader();
	LGShader* shader = lgNewRef(size, freeShader);
	shader->vsCount = 0;
	shader->fsCount = 0;
	gCtx.backend->newShader(shader);
	return shader;
}

LG_API int
lgShaderSource(LGShader* shader,
	LGShaderType type, const char* data, size_t size) {
	LGShaderSource* ss;
	unsigned* count;
	if (type == LGSHADER_VERTEX) {
		ss = shader->vs;
		count = &shader->vsCount;
	}
	else if (type == LGSHADER_FRAGMENT) {
		ss = shader->fs;
		count = &shader->fsCount;
	}
	else {
		return 1;
	}

	ss[*count].size = size;
	ss[*count].data = malloc(size);
	memcpy(ss[*count].data, data, size);
	(*count)++;
	return 0;
}

LG_API int
lgCompileShader(LGShader* shader, const char** err) {
	if(!shader->vsCount ||!shader->fsCount){
		*err = MISS_ERR;
		return 1;
	}
	int ret = gCtx.backend->compileShader(shader, err);
	for (unsigned i = 0; i < shader->vsCount; i++) {
		free(shader->vs[i].data);
	}
	for (unsigned i = 0; i < shader->fsCount; i++) {
		free(shader->fs[i].data);
	}
	shader->vsCount = shader->fsCount = 0;
	return ret;
}
